package com.itshen.jmh;

import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

@BenchmarkMode({Mode.Throughput, Mode.AverageTime}) // 测试方法平均执行时间
@OutputTimeUnit(TimeUnit.SECONDS) // 输出结果的时间粒度为微秒
@State(Scope.Benchmark) // 每个测试线程一个实例
public class JMHMapTest {

    static Map hashMap = new HashMap();
    static Map syncHashMap = Collections.synchronizedMap(new HashMap<>());
    static Map concurrentHashMap = new ConcurrentHashMap();

    @Setup
    public void setup() {
        for (int i = 0; i < 10000; i++) {
            hashMap.put(Integer.toString(i), Integer.toString(i));
            syncHashMap.put(Integer.toString(i), Integer.toString(i));
            concurrentHashMap.put(Integer.toString(i), Integer.toString(i));
        }
    }

    @Benchmark
    public void hashMapGet() {
        hashMap.get("10");
    }

    @Benchmark
    public void syncHashMapGet() {
        syncHashMap.get("10");
    }

    @Benchmark
    public void concurrentHashMapGet() {
        concurrentHashMap.get("10");
    }

    @Benchmark
    public void hashMapSize() {
        hashMap.size();
    }

    @Benchmark
    public void syncHashMapSize() {
        syncHashMap.size();
    }

    @Benchmark
    public void concurrentHashMapSize() {
        concurrentHashMap.size();
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                // 要测试的是哪个类的方法
                .include(JMHMapTest.class.getName())
                // 测试的时候需要排除的方法
                //.exclude()
                // 预热次数
                .warmupIterations(2)
                // 正式运行测试次数
                .measurementIterations(2)
                // 做3轮测试
                .forks(3)
                .build();

        new Runner(opt).run();
    }
}
